﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using Services.Exceptions;
using Services.Helpers;
using Services.Interfaces;
using Services.Mappers;
using Services.Models;
using System.Linq;
using Services.Models.XmlSoccer;

namespace Services.Implementations {

    public class XmlSoccerService : ISoccerService {

        public IList<LeagueWithMatchesModel> GetLeaguesWithMaches() {
            var file = DetermineLiveScoreFile();
            if(file == null) {
                throw new CustomException("file not found");
            }

            var content = File.ReadAllText(file);
            var matches = Utils.Deserialize<XmlSoccerMatchList>(content);
            var leagues = matches.MapToLeagueModel();
            return leagues;
        }

        public MatchModel GetMatch(string id) {
            var file = DetermineLiveScoreFile();
            if(file == null) {
                throw new CustomException("file not found");
            }

            var content = File.ReadAllText(file);
            var matches = Utils.Deserialize<XmlSoccerMatchList>(content);
            var match = matches.FirstOrDefault(x => x.Id == id);
            if(match == null) {
                throw new CustomException("match not found");
            }

            return match.MapToMatchModel();
        }

        public IList<MatchModel> GetMatches() {
            var file = DetermineLiveScoreFile();
            if(file == null) {
                throw new CustomException("file not found");
            }

            var content = File.ReadAllText(file);
            var matches = Utils.Deserialize<XmlSoccerMatchList>(content);

            return matches.Select(x => x.MapToMatchModel()).ToList();
        }

        public Teams GetAllTeams() {
            var file = Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/data/"), "teams.xml");
            if(!File.Exists(file)) {
                throw new CustomException("file not found");
            }
            return Utils.Deserialize<Teams>(File.ReadAllText(file));
        }

        public Leagues GetAllLeagues() {
            var file = Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/data/"), "leagues.xml");
            if(!File.Exists(file)) {
                throw new CustomException("file not found");
            }
            return Utils.Deserialize<Leagues>(File.ReadAllText(file));
        }

        public List<string> GetMatchHashtags(string id) {

            var tags = new List<string>();
            var match = GetMatch(id);
            if(match != null) {

                var teams = GetAllTeams();
                var home = teams.FirstOrDefault(x => x.Id == match.HomeTeamId);
                if(home != null && !string.IsNullOrEmpty(home.Hashtag)) {
                    tags.AddRange(home.Hashtag.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList());
                }

                var away = teams.FirstOrDefault(x => x.Id == match.AwayTeamId);
                if(away != null && !string.IsNullOrEmpty(away.Hashtag)) {
                    tags.AddRange(away.Hashtag.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList());
                }

                var leagues = GetAllLeagues();
                var league = leagues.FirstOrDefault(x => x.Name == match.League);
                if(league != null) {
                    tags.AddRange(league.Hashtag.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()).ToList());
                }
            }

            return tags;
        }


        private string DetermineLiveScoreFile() {

            var root = ConfigurationManager.AppSettings["xmlSoccerDataDirectory"];
            if(!Directory.Exists(root)) {
                throw new CustomException("directory not found");
            }

            var rootInfo = new DirectoryInfo(root);
            var directoryInfo = rootInfo.GetDirectories().OrderByDescending(x => x.CreationTime).FirstOrDefault();

            if(directoryInfo == null) {
                throw new CustomException("directory not found");
            }

            var file = directoryInfo.GetFiles().OrderByDescending(x => x.CreationTime).FirstOrDefault();

            if(file == null) {
                throw new CustomException("file not found");
            }

            if(file.Extension.ToLower() != ".xml") {
                throw new CustomException("incorrect file format");
            }

            return file.FullName;
        }
    }

}
